import 'dart:math';

import 'package:dio/dio.dart';
import 'package:logger/logger.dart';
import 'package:netflix_frontend/core/constants/api_url.dart';
import 'interceptors.dart';

class DioClient {
  late final Dio _dio;

  Logger logger = Logger(
      printer: PrettyPrinter(
    methodCount: 0,
    colors: true,
    printEmojis: true,
  ));

  DioClient()
      : _dio = Dio(
          BaseOptions(
              baseUrl: ApiUrl.baseURL,
              headers: {'Content-Type': 'application/json; charset=UTF-8'},
              responseType: ResponseType.json,
              sendTimeout: const Duration(seconds: 10),
              receiveTimeout: const Duration(seconds: 10)),
        )..interceptors.addAll([
            AuthorizationInterceptor(),
            LoggerInterceptor(),
          ]);

  Future<Response> get(
    String url, {
    Map<String, dynamic>? queryParams,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      final Response resp = await _dio.get(
        url,
        queryParameters: queryParams,
        options: options,
        cancelToken: cancelToken,
        onReceiveProgress: onReceiveProgress,
      );

      return resp;
    } on DioException catch (e) {
      logger.e("ERROR: network: get", error: e);
      rethrow;
    }
  } // GET

  Future<Response> post(
    String url, {
    dynamic data,
    Map<String, dynamic>? queryParams,
    Options? options,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      final Response resp = await _dio.post(
        url,
        data: data,
        options: options,
        onSendProgress: onSendProgress,
        onReceiveProgress: onReceiveProgress,
      );

      return resp;
    } catch (e) {
      logger.e("ERROR: network: post", error: e);
      rethrow;
    }
  } // POST

  Future<Response> put(
    String url, {
    dynamic data,
    Map<String, dynamic>? queryParams,
    Options? options,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      final Response resp = await _dio.put(
        url,
        data: data,
        queryParameters: queryParams,
        options: options,
        cancelToken: cancelToken,
        onSendProgress: onSendProgress,
        onReceiveProgress: onReceiveProgress,
      );

      return resp;
    } catch (e) {
      logger.e("ERROR: network: put", error: e);
      rethrow;
    }
  } // PUT

  Future<dynamic> delete(
    String url, {
    dynamic data,
    Map<String, dynamic>? queryParams,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    try {
      final Response resp = await _dio.delete(
        url,
        data: data,
        queryParameters: queryParams,
        options: options,
        cancelToken: cancelToken,
      );

      return resp;
    } catch (e) {
      logger.e("ERROR: network: delete", error: e);
      rethrow;
    }
  } // DELETE
}

// DONE
